﻿using UnityEngine;
using System.Collections;

//[RequireComponent(typeof(LegionTouchCamKeys))]
//[RequireComponent(typeof(LegionTouchCamMouse))]
public class PvpCamera : MonoBehaviour {
	
	GameObject _target;
	Transform _targetTrans;
	new public Transform transform;
	public bool freecamMode;
	
	Vector3 _moveVector;
	
	private float _currDistance;    // actual distance
	private float _currRotation;    // actual rotation
	private float _currTilt;        // actual tilt
	
	public Transform _followTarget;
	public bool IsFollowing
	{
		get { return FollowTarget != null; }
	}
	public Transform FollowTarget
	{
		get { return _followTarget; }
	}
	
	public Transform TargetTransform
	{
		get { return _targetTrans; }
	}
	
	public Vector3 LookAt;          // Desired lookat position
	public float InitialDistance;
	public float Distance;          // Desired distance (units, ie Meters)
	public float Rotation;          // Desired rotation (degrees)
	public float Tilt;              // Desired tilt (degrees)
	
	public bool Smoothing;          // Should the camera "slide" between positions and targets?
	public float MoveDampening;     // How "smooth" should the camera moves be?  Note: Smaller numbers are smoother
	public float ZoomDampening;     // How "smooth" should the camera zooms be?  Note: Smaller numbers are smoother
	public float RotationDampening; // How "smooth" should the camera rotations be?  Note: Smaller numbers are smoother
	public float TiltDampening;     // How "smooth" should the camera tilts be?  Note: Smaller numbers are smoother
	
	public Vector3 MinBounds;       // Minimum x,y,z world position for camera target
	public Vector3 MaxBounds;       // Maximum x,y,z world position for camera target
	
	public float MinDistance;       // Minimum distance of camera from target
	public float MaxDistance;       // Maximum distance of camera from target
	
	public float MinTilt;           // Minimum tilt (degrees)
	public float MaxTilt;           // Maximum tilt (degrees)
	public float BackTakeCamWaitTime;
	
	
	void Awake()
	{
		transform = gameObject.transform;
		CreateTarget();
	}
	
	public void Reset()
	{
		Smoothing = true;
		
		
		LookAt = new Vector3(0, 0, 0);
		MoveDampening = 5f;
		MinBounds = new Vector3(-100, -100, -100);
		MaxBounds = new Vector3(100, 100, 100);
		
		InitialDistance = 6.6f;
		Distance = 6.6f;
		MinDistance = 2;//3;
		MaxDistance = 12;//12;
		ZoomDampening = 5f;
		
		Rotation = 0f;
		RotationDampening = 5f;
		
		//Tilt = 45f;
		MinTilt = -50;//0f;
		MaxTilt = 50f;
		TiltDampening = 5f;
		BackTakeCamWaitTime = 99999;//1.0f;
		
	}
	
	void Start()
	{
		_currDistance = Distance;
		_currRotation = Rotation;
		_currTilt = Tilt;
	}
	
	private void CreateTarget()
	{
		_target = GameObject.CreatePrimitive(PrimitiveType.Sphere);
		_target.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
		
		_target.renderer.material.color = Color.green;
		
		var targetCollider = _target.GetComponent<Collider>();
		if (targetCollider != null)
		{
			targetCollider.enabled = false;
		}
		
		MeshRenderer _targetRenderer = _target.GetComponent<MeshRenderer>();
		_targetRenderer.enabled = false;
		
		_target.name = "CameraTarget";
		_targetTrans = _target.transform;
		//_target.transform.position = LookAt;
	}
	
	bool IsDeltaRotZero()
	{
		float tolerence=0.01f;
		if(deltaRot>=0 && deltaRot<tolerence)
			return true;
		if(deltaRot>=360 && deltaRot<360+tolerence)
			return true;
		if(deltaRot>360-tolerence && deltaRot<=360)
			return true;
		if(deltaRot>=360*2 && deltaRot<360*2+tolerence)
			return true;
		if(deltaRot>360*2-tolerence && deltaRot<=360*2)
			return true;
		return false;
	}
	
	public float deltaRot;
	void LateUpdate()
	{
		if(freecamMode) {
			if(Time.timeSinceLevelLoad - touchTime>BackTakeCamWaitTime)
				isGoingToTakeCam=true;
		}
		if(isGoingToTakeCam) {
			/*
				_targetTrans.position = Vector3.Lerp(_targetTrans.position, freecamStartPos, Time.deltaTime * MoveDampening);
				_currTilt = Mathf.LerpAngle(_currTilt, freecamStartTilt, Time.deltaTime * TiltDampening);
				_currRotation = Mathf.LerpAngle(_currRotation, freecamStartRotation, Time.deltaTime * RotationDampening);
				Rotation = _currRotation;
				Tilt = _currTilt;
				LookAt = _targetTrans.position;
				deltaRot = Mathf.Abs(_currRotation-freecamStartRotation);

				if( (_targetTrans.position-freecamStartPos).sqrMagnitude< 0.0001f && Mathf.Abs(_currTilt-freecamStartTilt)<0.01f && IsDeltaRotZero()  ) {
					isGoingToTakeCam=false;
					FreeCamMode(false);
				}*/
			transform.position = Vector3.Lerp(transform.position, freecamStartPos, Time.deltaTime * MoveDampening);
			transform.rotation = Quaternion.Lerp(transform.rotation, freecamStartQuater, Time.deltaTime * RotationDampening);
			KeepVariables();
			if( (transform.position-freecamStartPos).sqrMagnitude<0.0001f && Quaternion.Angle(transform.rotation, freecamStartQuater) < 0.01f) {
				isGoingToTakeCam=false;
				FreeCamMode(false);
			}
		}
		else if(freecamMode) {
			if (IsFollowing) {
				LookAt = _followTarget.position;
			}
			else {
				_moveVector.y = 0;
				LookAt += Quaternion.Euler(0, Rotation, 0) * _moveVector;
			}
			//Tilt = Mathf.Clamp(Tilt, MinTilt, MaxTilt);
			//Distance = Mathf.Clamp(Distance, MinDistance, MaxDistance);
			
			//_currDistance = Distance;
			
			_currRotation = Mathf.LerpAngle(_currRotation, Rotation, Time.deltaTime * RotationDampening);
			_currDistance = Mathf.Lerp(_currDistance, Distance, Time.deltaTime * ZoomDampening);
			_currTilt = Mathf.LerpAngle(_currTilt, Tilt, Time.deltaTime * TiltDampening);
			_targetTrans.position = Vector3.Lerp(_targetTrans.position, LookAt, Time.deltaTime * MoveDampening);
			
			
			_moveVector = Vector3.zero;
			
			//update camera
			var rotation = Quaternion.Euler(_currTilt, _currRotation, transform.rotation.eulerAngles.z);
			var v = new Vector3(0.0f, 0.0f, -_currDistance);
			var position = rotation * v + _targetTrans.position;
			
			transform.rotation = rotation;
			transform.position = position;
			
		}
		else {
			KeepVariables();
			
		}
	}
	
	void KeepVariables()
	{
		//LookAt = transform.position + transform.forward * Distance;
		_targetTrans.position = LookAt;
		
		Distance = InitialDistance;
		Rotation = transform.rotation.eulerAngles.y;
		Tilt = transform.rotation.eulerAngles.x;
		
		if(Tilt>=270 && Tilt<=360)
			Tilt = Tilt-360;
		_currRotation = Rotation;
		_currTilt = Tilt;
		_currDistance = Distance;
	}
	
	public void SetDistance(float _dist)
	{
		if(_dist<MinDistance)
			_dist=MinDistance;
		if(_dist>MaxDistance)
			_dist=MaxDistance;
		Distance = _dist+1;
	}
	
	bool isGoingToTakeCam;
	Vector3 freecamStartPos;
	Quaternion freecamStartQuater;
	
	float touchTime;
	float freecamStartTilt;
	float freecamStartRotation;
	bool isTiltHappened;
	bool isMoveHappened;
	bool isRotateHappened;
	
	void SaveStartPos()
	{
		if(CharacterViewer.Instance!=null)
			freecamStartPos = CharacterViewer.Instance.OriginalCamTrans[0].position;
		else
			freecamStartPos = transform.position;
	}
	
	void SaveStartRot()
	{
		if(CharacterViewer.Instance!=null)
			freecamStartQuater = CharacterViewer.Instance.OriginalCamTrans[0].rotation;
		else
			freecamStartQuater = transform.rotation;
	}
	
	public void AddToPosition(float dx, float dy, float dz)
	{
		TouchHappened();
		if(!isMoveHappened) {
			isMoveHappened=true;
			SaveStartPos();
			if(!isTiltHappened) {
				isTiltHappened=true;
				SaveStartRot();
				//freecamStartTilt= Tilt;
			}
			if(!isRotateHappened) {
				isRotateHappened=true;
				SaveStartRot();
				//freecamStartRotation = Rotation;
			}
		}
		_moveVector += new Vector3(dx, dy, dz);
	}
	
	public void ChangeZoom()
	{
		TouchHappened();
		if(!isMoveHappened) {
			isMoveHappened=true;
			SaveStartPos();
			if(!isTiltHappened) {
				isTiltHappened=true;
				SaveStartRot();
				//freecamStartTilt= Tilt;
			}
			if(!isRotateHappened) {
				isRotateHappened=true;
				SaveStartRot();
				//freecamStartRotation = Rotation;
			}
		}
	}
	
	public void ChangeTilt()
	{
		TouchHappened();
		if(!isTiltHappened) {
			isTiltHappened=true;
			//freecamStartTilt= Tilt;
			SaveStartRot();
			if(!isMoveHappened) {
				isMoveHappened=true;
				SaveStartPos();
			}
			if(!isRotateHappened) {
				isRotateHappened=true;
				//freecamStartRotation = Rotation;
			}
		}
	}
	
	public void ChangeRotation()
	{
		TouchHappened();
		if(!isRotateHappened) {
			isRotateHappened=true;
			//freecamStartRotation = Rotation;
			SaveStartRot();
			if(!isMoveHappened) {
				isMoveHappened=true;
				SaveStartPos();
			}
			if(!isTiltHappened) {
				isTiltHappened=true;
				//freecamStartTilt= Tilt;
			}
		}
	}
	
	public void TouchHappened()
	{
		if(CharacterViewer.Instance!=null)
			BackTakeCamWaitTime=99999;
		touchTime=Time.timeSinceLevelLoad;
		isGoingToTakeCam=false;
		if(!freecamMode) {
			FreeCamMode(true);
		}
	}
	
	
	void FreeCamMode(bool bActivate)
	{
		
		//CamTakeSetting.Instance.bPauseCam=true;
		freecamMode = bActivate;
		if(!bActivate) {
			isTiltHappened=false;
			isMoveHappened=false;
			isRotateHappened=false;
		}
		
		if(BattleSetting.Instance!=null)
			BattleSetting.Instance.ToggleAtkCamFocus(!bActivate);
	}
	
	public void DeactivateFreeCam()
	{
		if(freecamMode) {
			if(BattleSetting.Instance!=null)
				BattleSetting.Instance.ToggleAtkCamFocus(true);
			freecamMode = false;
			if(!false) {
				isTiltHappened=false;
				isMoveHappened=false;
				isRotateHappened=false;
			}
		}
	}
	
	public void EndFollow()
	{
	}
	
	//	void OnGUI()
	//	{
	//		if (GUI.Button(  new Rect(100, 200, 80 , 30), "pause")  )
	//		{
	//			FreeCamMode(true);
	//		}
	//
	//		if (GUI.Button(  new Rect(100, 250, 80 , 30), "resume")  )
	//		{
	//			isGoingToTakeCam=true;
	//		}
	//	}
}
